﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace FACUI.BasicClass
{
    /// <summary>
    /// 无岔区段
    /// </summary>
    public class WCQD : Sharp
    {
        private int i角度l;
        private int i角度r;
        private Point pointl;
        private Point pointr;

        public WCQD(MapData mapData, Point pt, int d, string subType)
            : base(mapData, pt, d)
        {
            base.digitList.Add(new Digit("红光带", "WCQD_H", 1));
            base.digitList.Add(new Digit("白光带", "WCQD_B", 1));
            base.changeStep = 1;
            base.text = "";
            base.sharpType = "sbWCQD";
            this.changeSubType(subType);
        }

        public WCQD(MapData mapData, Point pt, int d, string subType, int width, int height)
            : base(mapData, pt, d)
        {
            base.digitList.Add(new Digit("红光带", "WCQD_H", 1));
            base.digitList.Add(new Digit("白光带", "WCQD_B", 1));
            base.changeStep = 1;
            base.text = "";
            base.sharpType = "sbWCQD";
            this.changeSubType(subType);
            if (width > 0)
            {
                base.sizeDefineWidth = width;
            }
            if (height > 0)
            {
                base.sizeDefineHeight = height;
            }
        }

        public override void addSize(int r)
        {
            if (!"0".Equals(base.subType) && !"2".Equals(base.subType))
            {
                if ((base.sizeDefineWidth <= 1) && (r <= 0))
                {
                    return;
                }
                if (r <= 0)
                {
                    switch (base.direction)
                    {
                        case 2:
                        case 3:
                            base.pointX++;
                            base.sizeDefineWidth += r;
                            goto Label_01AB;
                    }
                    base.sizeDefineWidth += r;
                }
                else
                {
                    switch (base.direction)
                    {
                        case 2:
                        case 3:
                            base.pointX--;
                            base.sizeDefineWidth += r;
                            goto Label_01AB;
                    }
                    base.sizeDefineWidth += r;
                }
            }
            else if (((base.sizeDefineHeight > 1) && (base.sizeDefineWidth > 1)) || (r > 0))
            {
                switch (base.direction)
                {
                    case 0:
                        base.sizeDefineWidth += r;
                        goto Label_01AB;

                    case 2:
                        base.sizeDefineHeight += r;
                        goto Label_01AB;

                    case 3:
                        base.pointY -= r;
                        base.sizeDefineHeight += r;
                        base.sizeDefineWidth += r;
                        goto Label_01AB;
                }
                base.sizeDefineHeight += r;
                base.sizeDefineWidth += r;
            }
        Label_01AB:
            this.resetSize();
        }

        public override void addSize(int d, Point oldPoint, int oldWidth, int oldHeight, int width, int height)
        {
            switch ((d % 8))
            {
                case 0:
                    base.pointY = oldPoint.Y + height;
                    base.sizeDefineHeight = oldHeight - height;
                    break;

                case 1:
                    base.pointY = oldPoint.Y + height;
                    base.sizeDefineHeight = oldHeight - height;
                    base.sizeDefineWidth = oldWidth + width;
                    break;

                case 2:
                    base.sizeDefineWidth = oldWidth + width;
                    break;

                case 3:
                    base.sizeDefineHeight = oldHeight + height;
                    base.sizeDefineWidth = oldWidth + width;
                    break;

                case 4:
                    base.sizeDefineHeight = oldHeight + height;
                    break;

                case 5:
                    base.pointX = oldPoint.X + width;
                    base.sizeDefineWidth = oldWidth - width;
                    base.sizeDefineHeight = oldHeight + height;
                    break;

                case 6:
                    base.pointX = oldPoint.X + width;
                    base.sizeDefineWidth = oldWidth - width;
                    break;

                case 7:
                    base.pointX = oldPoint.X + width;
                    base.pointY = oldPoint.Y + height;
                    base.sizeDefineWidth = oldWidth - width;
                    base.sizeDefineHeight = oldHeight - height;
                    break;
            }
            if (base.sizeDefineWidth <= 0)
            {
                base.sizeDefineWidth = 1;
            }
            if (base.sizeDefineHeight <= 0)
            {
                base.sizeDefineHeight = 1;
            }
            this.resetSize();
        }

        public override bool changeSubType(string newSubType)
        {
            if (!((("0".Equals(newSubType) || "1".Equals(newSubType)) || "2".Equals(newSubType)) || "3".Equals(newSubType)))
            {
                return false;
            }
            if ("0".Equals(newSubType) || "2".Equals(newSubType))
            {
                switch ((base.direction % 4))
                {
                    case 1:
                        base.sizeDefine = new Size(3, 3);
                        goto Label_00E4;

                    case 2:
                        base.sizeDefine = new Size(2, 3);
                        goto Label_00E4;

                    case 3:
                        base.sizeDefine = new Size(3, 3);
                        goto Label_00E4;
                }
                base.sizeDefine = new Size(3, 2);
            }
            else
            {
                int num1 = base.direction % 4;
                base.sizeDefine = new Size(3, 2);
            }
        Label_00E4:
            base.subType = newSubType;
            this.resetSize();
            return true;
        }

        public override void checkLine(int[][][] array4checkLine)
        {
            int num;
            if ("0".Equals(base.subType) || "2".Equals(base.subType))
            {
                if (0 == base.direction)
                {
                    for (num = 0; num < base.sizeDefineWidth; num++)
                    {
                        Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + 1, 0);
                    }
                }
                else if (1 == base.direction)
                {
                    if (base.sizeDefineWidth == base.sizeDefineHeight)
                    {
                        for (num = 0; num < base.sizeDefineWidth; num++)
                        {
                            Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + num, 1);
                        }
                    }
                }
                else if (2 == base.direction)
                {
                    for (num = 0; num < base.sizeDefineHeight; num++)
                    {
                        Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + 1, base.pointY + num, 2);
                    }
                }
                else if ((3 == base.direction) && (base.sizeDefineWidth == base.sizeDefineHeight))
                {
                    for (num = 0; num < base.sizeDefineWidth; num++)
                    {
                        Sharp.tryAddArray4checkLine(array4checkLine, (base.pointX + base.sizeDefineWidth) - num, base.pointY + num, 3);
                    }
                }
            }
            else if (0 == base.direction)
            {
                Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + 1, base.pointY + 1, 3);
                for (num = 1; num < base.sizeDefineWidth; num++)
                {
                    Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + 1, 0);
                }
            }
            else if (1 == base.direction)
            {
                Sharp.tryAddArray4checkLine(array4checkLine, base.pointX, base.pointY, 1);
                for (num = 1; num < base.sizeDefineWidth; num++)
                {
                    Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + 1, 0);
                }
            }
            else if (2 == base.direction)
            {
                Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + base.sizeDefineWidth, base.pointY, 3);
                for (num = 0; num < (base.sizeDefineWidth - 1); num++)
                {
                    Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + 1, 0);
                }
            }
            else if (3 == base.direction)
            {
                Sharp.tryAddArray4checkLine(array4checkLine, (base.pointX + base.sizeDefineWidth) - 1, base.pointY + 1, 1);
                for (num = 0; num < (base.sizeDefineWidth - 1); num++)
                {
                    Sharp.tryAddArray4checkLine(array4checkLine, base.pointX + num, base.pointY + 1, 0);
                }
            }
        }

        public override void createDigit(string kglDesc)
        {
            string[] strArray = kglDesc.Split(new char[] { ',' });
            Digit digit = null;
            string[] strArray2 = strArray[1].Split(new char[] { ';' });
            digit = base.getDigit("WCQD_H");
            digit.name = strArray2[0];
            digit.isLogic = "1".Equals(strArray2[1]);
            digit.ad = int.Parse(strArray2[2]);
            strArray2 = strArray[2].Split(new char[] { ';' });
            digit = base.getDigit("WCQD_B");
            digit.name = strArray2[0];
            digit.isLogic = "1".Equals(strArray2[1]);
            digit.ad = int.Parse(strArray2[2]);
        }

        public override double distance(Point p, Size r)
        {
            double num = Math.Pow((p.X - (((((double)(this.rectReal.Right + this.rectReal.Left)) / 2.0) * r.Width) / 2.0)) / 2.0, 2.0);
            double num2 = Math.Pow((p.Y - (((((double)(this.rectReal.Bottom + this.rectReal.Top)) / 2.0) * r.Height) / 2.0)) / 2.0, 2.0);
            if (!"0".Equals(base.subType) && !"2".Equals(base.subType))
            {
                return (Math.Sqrt(num2 + num2) + 0.001);
            }
            switch (base.direction)
            {
                case 0:
                    return (Math.Sqrt(num2 + num2) + 0.001);

                case 2:
                    return (Math.Sqrt(num + num) + 0.001);
            }
            return Math.Sqrt((num + num2) + 0.001);
        }

        public override void draw(Graphics g, MapSet ct, Pen usePen)
        {
            if (base.inShowArea())
            {
                Rectangle rectangle;
                this.resetSize();
                if ("0".Equals(base.subType) || "2".Equals(base.subType))
                {
                    rectangle = new Rectangle(((this.rectReal.Left * ct.gridsize.Width) / 2) + ct.offset.X, ((this.rectReal.Top * ct.gridsize.Height) / 2) + ct.offset.Y, (this.rectReal.Width * ct.gridsize.Width) / 2, (this.rectReal.Height * ct.gridsize.Height) / 2);
                }
                else
                {
                    rectangle = new Rectangle(((this.rectReal.Left * ct.gridsize.Width) / 2) + ct.offset.X, ((this.rectReal.Top * ct.gridsize.Height) / 2) + ct.offset.Y, (this.rectReal.Width * ct.gridsize.Width) / 2, (2 * ct.gridsize.Height) / 2);
                }
                StringFormat format = new StringFormat(StringFormatFlags.NoClip)
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                };
                base.linePen.Color = base.lineColor;
                base.linePen.Width = ct.lineWidth;
                Pen pen = (usePen != null) ? usePen : base.linePen;
                pen.Width = (ct.gridsize.Width >= 8) ? pen.Width : 1f;
                if (MapData.开始打印)
                {
                    pen = new Pen(Color.Black, pen.Width);
                }
                if ("0".Equals(base.subType) || "2".Equals(base.subType))
                {
                    if (0 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY + 1;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY + 1;
                        this.i角度l = 180;
                        this.i角度r = 0;
                        g.DrawLine(pen, base.grid2pix(this.pointl, ct.gridsize, ct.offset), base.grid2pix(this.pointr, ct.gridsize, ct.offset));
                        rectangle.Y = (rectangle.Top + (ct.gridsize.Height / 2)) + 4;
                        format.LineAlignment = StringAlignment.Near;
                    }
                    else if (1 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY + base.sizeDefineHeight;
                        this.i角度l = 0x87;
                        this.i角度r = 0x13b;
                        g.DrawLine(pen, base.grid2pix(this.pointl, ct.gridsize, ct.offset), base.grid2pix(this.pointr, ct.gridsize, ct.offset));
                        format.LineAlignment = StringAlignment.Near;
                    }
                    else if (2 == base.direction)
                    {
                        this.pointl.X = base.pointX + 1;
                        this.pointl.Y = base.pointY;
                        this.pointr.X = base.pointX + 1;
                        this.pointr.Y = base.pointY + base.sizeDefineHeight;
                        this.i角度l = 90;
                        this.i角度r = 270;
                        g.DrawLine(pen, base.grid2pix(this.pointl, ct.gridsize, ct.offset), base.grid2pix(this.pointr, ct.gridsize, ct.offset));
                        rectangle.X = (rectangle.Left + (ct.gridsize.Width / 2)) + 4;
                        rectangle.Width = 3 * ct.gridsize.Width;
                        format.Alignment = StringAlignment.Near;
                    }
                    else if (3 == base.direction)
                    {
                        this.pointl.X = base.pointX + base.sizeDefineWidth;
                        this.pointl.Y = base.pointY;
                        this.pointr.X = base.pointX;
                        this.pointr.Y = base.pointY + base.sizeDefineHeight;
                        this.i角度l = 0x2d;
                        this.i角度r = 0xe1;
                        g.DrawLine(pen, base.grid2pix(this.pointl, ct.gridsize, ct.offset), base.grid2pix(this.pointr, ct.gridsize, ct.offset));
                        format.LineAlignment = StringAlignment.Near;
                    }
                }
                else
                {
                    format.LineAlignment = StringAlignment.Near;
                    Point[] ptmp = null;
                    if (0 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY + 2;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY + 1;
                        this.i角度l = 0xe1;
                        this.i角度r = 0;
                        ptmp = new Point[] {base.grid2pix(this.pointl, ct.gridsize, ct.offset),
                                                    base.grid2pix(new Point(base.pointX + 1, base.pointY + 1), ct.gridsize, ct.offset),
                                                    base.grid2pix(this.pointr, ct.gridsize, ct.offset)
                                                    };
                        g.DrawLines(pen,ptmp);
                        //g.DrawLine(pen, base.grid2pix(this.pointl, ct.gridsize, ct.offset), base.grid2pix(new Point(base.pointX + 1, base.pointY + 1), ct.gridsize, ct.offset));
                        //g.DrawLine(pen, base.grid2pix(new Point(base.pointX + 1, base.pointY + 1), ct.gridsize, ct.offset), base.grid2pix(this.pointr, ct.gridsize, ct.offset));
                        rectangle.Y = base.grid2pix(new Point(base.pointX + base.sizeDefineWidth, base.pointY + 1), ct.gridsize, ct.offset).Y + 3;
                    }
                    else if (1 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY + 1;
                        this.i角度l = 0x87;
                        this.i角度r = 0;
                        ptmp=new Point[]{ base.grid2pix(this.pointl, ct.gridsize, ct.offset), 
                                          base.grid2pix(new Point(base.pointX + 1, base.pointY + 1), ct.gridsize, ct.offset),
                                          base.grid2pix(this.pointr, ct.gridsize, ct.offset)
                                        };
                        g.DrawLines(pen, ptmp);
                        rectangle.Y = base.grid2pix(new Point(base.pointX + base.sizeDefineWidth, base.pointY + 1), ct.gridsize, ct.offset).Y + 3;
                    }
                    else if (2 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY + 1;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY;
                        this.i角度l = 180;
                        this.i角度r = 0x2d;
                        ptmp=new Point[]{base.grid2pix(this.pointl, ct.gridsize, ct.offset),
                                         base.grid2pix(new Point((base.pointX + base.sizeDefineWidth) - 1, base.pointY + 1), ct.gridsize, ct.offset),
                                         base.grid2pix(this.pointr, ct.gridsize, ct.offset)
                                        };
                        g.DrawLines(pen,ptmp);
                        rectangle.Y = base.grid2pix(new Point((base.pointX + base.sizeDefineWidth) - 1, base.pointY + 1), ct.gridsize, ct.offset).Y + 3;
                    }
                    else if (3 == base.direction)
                    {
                        this.pointl.X = base.pointX;
                        this.pointl.Y = base.pointY + 1;
                        this.pointr.X = base.pointX + base.sizeDefineWidth;
                        this.pointr.Y = base.pointY + 2;
                        this.i角度l = 180;
                        this.i角度r = 0x13b;
                        ptmp=new Point[]{base.grid2pix(this.pointl, ct.gridsize, ct.offset),
                                         base.grid2pix(new Point((base.pointX + base.sizeDefineWidth) - 1, base.pointY + 1), ct.gridsize, ct.offset),
                                         base.grid2pix(this.pointr, ct.gridsize, ct.offset)
                                        };
                        g.DrawLines(pen,ptmp);
                        rectangle.Y = base.grid2pix(new Point(base.pointX + base.sizeDefineWidth, base.pointY + 1), ct.gridsize, ct.offset).Y + 3;
                    }
                }
                if (!(base.isHideTxt || (((int)(base.txtSize * ((ct.gridsize.Width * 1.0) / 10.0))) < 4)))
                {
                    g.DrawString(base.text, new Font(base.txtFont, (float)((int)(base.txtSize * ((ct.gridsize.Width * 1.0) / 10.0))), FontStyle.Regular), new SolidBrush(MapData.开始打印 ? Color.Black : base.txtColor), rectangle, format);
                }
            }
        }

        public Point getAnotherPoint(Point pt)
        {
            if (base.text.Equals("D1G"))
            {
            }
            return (pt.Equals(this.pointr) ? this.pointl : this.pointr);
        }

        public override Point getPoint(char c)
        {
            Point point = new Point(-1, -1);
            switch (c)
            {
                case 'L':
                    return this.pointl;

                case 'R':
                    return this.pointr;
            }
            return point;
        }

        public override Point getPoint(char c, out int 方向)
        {
            Point point = this.getPoint(c);
            方向 = 0;
            if (c == 'L')
            {
                方向 = this.i角度l;
                return point;
            }
            if (c == 'R')
            {
                方向 = this.i角度r;
            }
            return point;
        }

        public override bool hasHotPoint(int d)
        {
            if (!"0".Equals(base.subType) && !"2".Equals(base.subType))
            {
                switch (d)
                {
                    case 2:
                    case 6:
                        return true;
                }
                return false;
            }
            if ((base.direction == 1) || (base.direction == 3))
            {
                return true;
            }
            switch (d)
            {
                case 0:
                case 4:
                    return (base.direction == 2);

                case 2:
                case 6:
                    return (base.direction == 0);
            }
            return false;
        }

        public override bool hasPoint(Point pt)
        {
            return (pt.Equals(this.pointr) || pt.Equals(this.pointl));
        }

        public override bool hasPoint(Point pt, out char flag)
        {
            flag = 'N';
            if (pt.Equals(this.pointr))
            {
                flag = 'R';
                return true;
            }
            if (pt.Equals(this.pointl))
            {
                flag = 'L';
                return true;
            }
            return false;
        }

        public override void onSpaceChar()
        {
            base.direction = (base.direction + base.changeStep) % 4;
            if ("0".Equals(base.subType) || "2".Equals(base.subType))
            {
                switch ((base.direction % 4))
                {
                    case 1:
                        base.sizeDefine = new Size(3, 3);
                        goto Label_00B5;

                    case 2:
                        base.sizeDefine = new Size(2, 3);
                        goto Label_00B5;

                    case 3:
                        base.sizeDefine = new Size(3, 3);
                        goto Label_00B5;
                }
                base.sizeDefine = new Size(3, 2);
            }
            else
            {
                int num1 = base.direction % 4;
            }
        Label_00B5:
            this.resetSize();
        }

        public override void resetSize()
        {
            if ("0".Equals(base.subType) || "2".Equals(base.subType))
            {
                this.rectReal.Width = base.sizeDefineWidth * 2;
                this.rectReal.Height = base.sizeDefineHeight * 2;
                if (0 == base.direction)
                {
                    this.rectReal.Location = new Point(base.pointX * 2, (base.pointY * 2) + 1);
                    this.rectReal.Height = 2;
                }
                else if (1 == base.direction)
                {
                    this.rectReal.Location = new Point(base.pointX * 2, base.pointY * 2);
                }
                else if (2 == base.direction)
                {
                    this.rectReal.Location = new Point((base.pointX * 2) + 1, base.pointY * 2);
                    this.rectReal.Width = 2;
                }
                else if (3 == base.direction)
                {
                    this.rectReal.Location = new Point(base.pointX * 2, base.pointY * 2);
                }
            }
            else
            {
                if ((base.direction == 0) || (3 == base.direction))
                {
                    this.rectReal.Location = new Point(base.pointX * 2, (base.pointY * 2) + 1);
                }
                else
                {
                    this.rectReal.Location = new Point(base.pointX * 2, (base.pointY * 2) - 1);
                }
                this.rectReal.Width = base.sizeDefineWidth * 2;
                this.rectReal.Height = 4;
            }
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder("");
            builder.Append(StringUtil.TrimAndPadRight4ASCII(base.text, 1)).Append("无岔区段");
            switch (int.Parse(base.subType))
            {
                case 0:
                    builder.Append("->信号直线段:");
                    break;

                case 1:
                    builder.Append("->信号弯线段:");
                    break;

                case 2:
                    builder.Append("->无信号直线段:");
                    break;

                case 3:
                    builder.Append("->无信号弯线段:");
                    break;
            }
            builder.Append(" 坐标(").Append(base.pointX).Append(',').Append(base.pointY).Append(')');
            return builder.ToString();
        }

        public override string toStringKgl()
        {
            Digit[] digitArray = base.digitList.ToArray();
            StringBuilder builder = new StringBuilder("");
            builder.Append("").Append(digitArray[0].name).Append(";").Append(digitArray[0].isLogic ? "1" : "0").Append(";").Append(digitArray[0].ad).Append(",").Append(digitArray[1].name).Append(";").Append(digitArray[1].isLogic ? "1" : "0").Append(";").Append(digitArray[1].ad);
            return builder.ToString();
        }

        public override string toStringXiangshu()
        {
            return string.Concat(new object[] { 
                base.text, ",", base.sharpType, ",", base.subType, ",", (base.lineColor.R + (base.lineColor.G << 8)) + (base.lineColor.B << 0x10), ",", base.direction, ",", base.pointX, ",", base.pointY, ",", base.sizeDefineWidth, ",", 
                base.sizeDefineHeight, ",", base.txtSize, ",", ((base.txtColor.B << 0x10) + (base.txtColor.G << 8)) + base.txtColor.R, ",", base.txtFont, ",", base.isHideTxt ? "1" : "0"
             });
        }

        public override void xuanzhuan180(Point center)
        {
            Point point = new Point(base.pointX + base.sizeDefineWidth, base.pointY + base.sizeDefineHeight);
            Point point2 = new Point(center.X - point.X, center.Y - point.Y);
            if ("1".Equals(base.subType) || "3".Equals(base.subType))
            {
                switch (base.direction)
                {
                    case 0:
                    case 2:
                        base.direction = 2 - base.direction;
                        break;

                    case 1:
                        base.direction = 3;
                        break;

                    case 3:
                        base.direction = 1;
                        break;
                }
            }
            base.point = point2;
        }
    }
}

